package com.qf.controller;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 *
 * 秒杀小Demo
 * @author lixu
 */
@RestController
@RequestMapping("/seckill")
public class SecKillController {

    //本地锁   JUC 最新版的锁
    public static Lock lock = new ReentrantLock();

    //商品
    private static Map<String,Integer> itemNum = new HashMap<>();
    //订单
    private static Map<String,Integer> orderNum = new HashMap<>();

    static {
        itemNum.put("牙刷",10000);

        orderNum.put("牙刷",0);//11000

    }

    /**
     * 分布式锁
     */
/*
    @GetMapping("/start")
    public String startSeckill(String name){
        lock.lock();//上锁
        Integer num = itemNum.get(name);
        //减少商品
        num--;
        itemNum.put(name,num);
        //增加一份订单
        Integer num1 = orderNum.get(name);
        num1++;
        orderNum.put(name,num1);
        //解锁
        lock.unlock();
        //3. 返回信息
        return "抢购成功！！！" + name + "： 剩余库存数为 - " + itemNum.get(name)
                + "，订单数为 - " + orderNum.get(name);
    }
*/

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 初始化数据
     */
    @PostConstruct
    public void adc(){
        //itemNum.put("牙刷",10000);
        redisTemplate.opsForValue().set("item:牙刷",10000);

        //orderNum.put("牙刷",0);//11000
        redisTemplate.opsForValue().set("order:牙刷",0);

    }


/*      本地锁的问题
@GetMapping("/start")
    public String startSeckill(String name){
        lock.lock();//上锁
        Integer num = (Integer) redisTemplate.opsForValue().get("item:" + name);
        //减少商品
        num--;
        redisTemplate.opsForValue().set("item:" + name,num);
        //增加一份订单
        Integer num1 = (Integer) redisTemplate.opsForValue().get("order:" + name);
        num1++;
        redisTemplate.opsForValue().set("order:" + name,num1);
        //解锁
        lock.unlock();
        //3. 返回信息
        return "抢购成功！！！" + name + "： 剩余库存数为 - " + redisTemplate.opsForValue().get("item:" + name)
                + "，订单数为 - " + redisTemplate.opsForValue().get("order:" + name);
    }*/

    @Autowired
    private CuratorFramework cf;//zookeeper的客户端
    /**
     * zookeeper： 分布式锁
     * @param name
     * @return
     */
    @GetMapping("/start")
    public String startSeckill(String name) throws Exception{
        //============= 创建zookeeper锁对象 ==================
        InterProcessMutex lock = new InterProcessMutex(cf,"/lock");//临时有序节点  ：序号中最小的
        lock.acquire();//上锁
        Integer num = (Integer) redisTemplate.opsForValue().get("item:" + name);
        //减少商品
        num--;
        redisTemplate.opsForValue().set("item:" + name,num);
        //增加一份订单
        Integer num1 = (Integer) redisTemplate.opsForValue().get("order:" + name);
        num1++;
        redisTemplate.opsForValue().set("order:" + name,num1);
        //解锁
        lock.release();
        //3. 返回信息
        return "抢购成功！！！" + name + "： 剩余库存数为 - " + redisTemplate.opsForValue().get("item:" + name)
                + "，订单数为 - " + redisTemplate.opsForValue().get("order:" + name);
    }






}
